<template>
  <div class="all">
    <van-nav-bar
      fixed
      placeholder
      safe-area-inset-top
      :title="
        chatItem.from.name !== userInfo.userName
          ? chatItem.from.name
          : chatItem.to.name
      "
      left-arrow
      @click-left="back"
    />
    <div class="loading" v-if="showLoading">
      <van-loading type="spinner" />
    </div>
    <div class="bigbox" ref="contRef">
      <div v-for="(item, index) in imList" :key="index" class="chatbox">
        <div>
          <div class="time">
            <span>{{ getDate(item.timeStamp) }}</span>
          </div>
          <div class="chatcontent">
            <div class="head">
              <van-image
                v-show="item.from.id !== userInfo.uid"
                round
                :src="item.from.avatar || defaultAvatar"
                fit="cover"
              />
            </div>
            <div class="chattwo">
              <div
                :style="{
                  textAlign: item.from.id === userInfo.uid ? 'right' : 'left',
                }"
              >
                {{ item.from.name }}
              </div>
              <div v-if="item.type === 'message'">{{ item.msg }}</div>
              <div
                :style="{
                  textAlign: item.from.id === userInfo.uid ? 'right' : 'left',
                  background: 0,
                }"
              >
                <van-image
                  accept="image/png,image/jpeg,image/gif,image/jpg,image/svg+xml,image/webp,image/apng,image/avif,image/bmp"
                  v-if="
                    item.type === 'image/png' ||
                    item.type === 'image/jpeg' ||
                    item.type === 'image/gif' ||
                    item.type === 'image/jpg' ||
                    item.type === 'image/svg+xml' ||
                    item.type === 'image/webp' ||
                    item.type === 'image/apng' ||
                    item.type === 'image/avif' ||
                    item.type === 'image/bmp'
                  "
                  :src="item.url"
                  fit="cover"
                  @click="showImagePreview([item.url])"
                />
              </div>
            </div>
            <div class="head">
              <van-image
                v-show="item.from.id === userInfo.uid"
                round
                :src="item.from.avatar || defaultAvatar"
                fit="cover"
              />
            </div>
          </div>
        </div>
      </div>
      <div ref="move" />
    </div>
    <div class="slot"></div>
    <div class="sendchat">
      <van-uploader :after-read="onUpload">
        <van-icon name="photo-o" />
      </van-uploader>
      <van-popover v-model:show="showPopover" placement="top-start">
        <van-grid square clickable :border="false" column-num="6">
          <van-grid-item
            v-for="(item, i) in emoji"
            :key="i"
            :text="item"
            @click="sendwords += item"
          />
        </van-grid>
        <template #reference>
          <van-icon name="smile-o" />
        </template>
      </van-popover>
      <input
        v-model="sendwords"
        type="text"
        placeholder="请输入您想要的说的话"
      />
      <button @click="send">发送</button>
    </div>
    <div class="safe" />
  </div>
</template>

<script setup lang="ts">
import {
  ref,
  reactive,
  getCurrentInstance,
  onMounted,
  watch,
  nextTick,
} from "vue";
import { useRouter } from "vue-router";
import { getDate, queryIndexDBByPage } from "@/utils/utils";
import defaultAvatar from "@/assets/cat.jpeg";
import { emoji } from "@/utils/emoji";
import { uploadFile } from "@/api/upload";
import { showImagePreview } from "vant";
import indexedDBStore from "@/store/module/indexedDB";
import addressBookStore from "@/store/module/addressBook";
import { addData } from "@/utils/utils.ts";
import { sendNotification } from "@/utils/notification";
import chatListStore from "@/store/module/chatList";

let db = indexedDBStore();
let addressBook = addressBookStore();
let chatList = chatListStore();
const chatItem = history.state.chatItem;
// console.log(chatItem);
onMounted(() => {
  db.unReadCount -= chatItem.unReadCount;
  chatList.updateChatItemUnReadCount(chatItem.chatId);
  localStorage.setItem("unReadCount", String(db.unReadCount));
  showLoading.value = true;
  queryIndexDBByPage({
    page: page.value,
    pageSize: 10,
    db: db.indexedDB,
    tableName: "messages",
    queryIndex: "chatId",
    queryIndexValue: chatItem.chatId,
  }).then((res) => {
    console.log("res", res);
    let list = res.reverse();
    list.forEach((item: any) => {
      imList.push(item);
    });
  });
  setTimeout(() => {
    showLoading.value = false;
    observeFriendListScroll();
  }, 1000);
});
const global = getCurrentInstance()?.appContext.config.globalProperties.$global;
const router = useRouter();
const showLoading = ref(false);
const sendwords = ref("");
const canTop = ref(true);
const isGoBottom = ref(true);
const page = ref(1);
let imList: any = reactive([]);
const contRef = ref(null);
watch(
  imList,
  () => {
    imList.sort((a, b) => {
      return a.timeStamp - b.timeStamp;
    });
    nextTick(() => {
      if (isGoBottom.value) {
        scrollToBottom();
      }
      setTimeout(() => {
        if (isGoBottom.value) {
          scrollToBottom();
        }
      }, 1000);
    });
  },
  { deep: true }
);
const showPopover = ref(false);
const userInfo = JSON.parse(localStorage.getItem("userInfo"));
global.ws.onmessage = (e: any) => {
  isGoBottom.value = true;
  const data = JSON.parse(e.data);
  console.log("onmessage", data);
  if (data.type === "notice") {
    if (data.msgType === "friendRequest") {
      addressBook.addUnReadCount(data.data);
      addressBook.updateAddFriendList(data.data);
    }
  } else {
    if (data.type === "message" && data.from.id !== userInfo.uid) {
      sendNotification(`${data.from.name}：${data.msg}`, data.from.avatar);
    } else if (data.url && data.from.id !== userInfo.uid) {
      sendNotification(`${data.from.name}：图片`, data.from.avatar);
    }
    if (data.chatId === chatItem.chatId) {
      imList.push(data);
    }
    chatList.addChat(data, "inChat");
    addData(db.indexedDB, "messages", data);
  }
};
function observeFriendListScroll() {
  let chatBox: any = contRef.value;
  chatBox.addEventListener("scroll", (e: any) => {
    const scrollTop = chatBox.scrollTop || chatBox.scrollTop;
    if (scrollTop < 10 && canTop.value) {
      isGoBottom.value = false;
      console.log("scroll to top");
      canTop.value = false;
      page.value++;
      showLoading.value = true;
      queryIndexDBByPage({
        page: page.value,
        pageSize: 10,
        db: db.indexedDB,
        tableName: "messages",
        queryIndex: "chatId",
        queryIndexValue: chatItem.chatId,
      }).then((res) => {
        console.log(res);
        let list = res.reverse();
        list.forEach((item: any) => {
          imList.unshift(item);
        });
        showLoading.value = false;
        if (res.length !== 0) {
          canTop.value = true;
        }
      });
    }
  });
}
const scrollToBottom = () => {
  let scrollElem: any = contRef.value;
  scrollElem.scrollTo({
    top: scrollElem.scrollHeight,
    behavior: "smooth",
  });
};
const onUpload = (file: any) => {
  // console.log(file.file);
  const formData = new FormData();
  formData.append("file", file.file);
  uploadFile(formData).then((res: any) => {
    if (res.code === 200) {
      global.ws.send(
        JSON.stringify({
          chatId: chatItem.chatId,
          type: file.file.type,
          from: {
            name: userInfo.userName,
            id: userInfo.uid,
            avatar: userInfo.userAvatar,
          },
          to: {
            name:
              chatItem.from.name !== userInfo.userName
                ? chatItem.from.name
                : chatItem.to.name,
            id:
              chatItem.from.id !== userInfo.uid
                ? chatItem.from.id
                : chatItem.to.id,

            avatar:
              chatItem.from.id !== userInfo.uid
                ? chatItem.from.avatar
                : chatItem.to.avatar,
          },
          url: res.path,
          fileName: res.name,
          timeStamp: new Date().getTime(),
        })
      );
    }
  });
};
const send = () => {
  if (sendwords.value.trim() !== "") {
    global.ws.send(
      JSON.stringify({
        chatId: chatItem.chatId,
        type: "message",
        from: {
          name: userInfo.userName,
          id: userInfo.uid,
          avatar: userInfo.userAvatar,
        },
        to: {
          name:
            chatItem.from.name !== userInfo.userName
              ? chatItem.from.name
              : chatItem.to.name,
          id:
            chatItem.from.id !== userInfo.uid
              ? chatItem.from.id
              : chatItem.to.id,

          avatar:
            chatItem.from.id !== userInfo.uid
              ? chatItem.from.avatar
              : chatItem.to.avatar,
        },
        msg: sendwords.value,
        timeStamp: new Date().getTime(),
      })
    );
    sendwords.value = "";
  } else {
  }
};
const back = () => {
  router.go(-1);
};
</script>

<style scoped lang="scss">
.loading {
  text-align: center;
  background-color: #fff;
  height: 30px;
}

.slot {
  height: 80px;
}

.all {
  height: 100vh;
  display: flex;
  flex-direction: column;
  background-color: #f2f2f2 !important;
}

.bigbox {
  padding-top: 15px;
  overflow-y: scroll;
  flex: 1;

  .time {
    text-align: center;

    span {
      background-color: #dadada;
      display: inline-block;
      color: #fff;
      font-size: 13px;
      padding: 2px 7px;
    }
  }

  .chatcontent {
    width: 100%;
    box-sizing: border-box;
    display: flex;
    align-items: center;
    justify-content: space-around;
    padding: 10px 15px;

    .head {
      width: 50px;

      .van-image {
        width: 50px;
        height: 50px;
      }
    }

    .chattwo {
      box-sizing: border-box;
      width: 60%;
      word-wrap: break-word;
      word-break: break-all;
      overflow: hidden;

      & > div:nth-child(1) {
        font-size: 13px;
        color: #ccc;
        margin-bottom: 5px;
      }

      & > div:nth-child(2) {
        padding: 10px 20px;
        font-size: 15px;
        background-color: #fff;
      }
    }
  }

  .call {
    font-size: 13px;
    text-align: center;
    padding-bottom: 10px;

    > span {
      display: inline-block;
      padding: 0px 4px;
      color: #fff;
      background-color: #ccc;

      .callnum {
        margin-left: 3px;
        color: #45b7cb;
      }
    }
  }
}

:deep(.van-grid) {
  width: 240px;
  height: 120px;
  overflow-y: scroll;
}

.sendchat {
  position: fixed;
  bottom: 0;
  width: 100vw;
  display: flex;
  justify-content: space-evenly;
  align-items: center;
  padding: 15px;
  background-color: #f6f6f6;

  .van-icon {
    font-size: 20px;
  }

  input {
    border: none;
    padding-left: 10px;
    color: #333;
    font-size: 14px;
    width: 60%;
    height: 33px;
  }

  button {
    width: 60px;
    height: 33px;
    border-radius: 16px;
    font-size: 14px;
    background-color: #45b7cb;
    color: #fff;
    border: none;
  }
}

.safe {
  background-color: #f6f6f6;
  padding-bottom: constant(safe-area-inset-bottom);
  padding-bottom: env(safe-area-inset-bottom);
}

:deep(.van-grid-item__text) {
  font-size: 20px;
}
</style>
